package cn.iocoder.yudao.module.wine.service.supplyinfo;

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.ip.core.Area;
import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum;
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
import cn.iocoder.yudao.module.trade.api.brokerage.BrokerageUserApi;
import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageUserDTO;
import cn.iocoder.yudao.module.wine.controller.admin.config.enums.ConfigEnum;
import cn.iocoder.yudao.module.wine.controller.admin.messageboard.vo.MessageBoardSaveReqVO;
import cn.iocoder.yudao.module.wine.controller.app.supplyinfo.enums.SupplyInfoEnum;
import cn.iocoder.yudao.module.wine.controller.app.supplyinfo.vo.*;
import cn.iocoder.yudao.module.wine.controller.app.supplymarket.vo.InfoPageReqVO;
import cn.iocoder.yudao.module.wine.controller.app.supplymarket.vo.MarketInfoListPageReqVO;
import cn.iocoder.yudao.module.wine.controller.app.supplyorderlog.enums.SupplyOrderLogEnum;
import cn.iocoder.yudao.module.wine.controller.app.userfans.enums.UserFansSubscribeEnum;
import cn.iocoder.yudao.module.wine.dal.dataobject.businessuser.BusinessUserDO;
import cn.iocoder.yudao.module.wine.dal.dataobject.config.WineConfigDO;
import cn.iocoder.yudao.module.wine.dal.dataobject.countnameconfig.CountNameConfigDO;
import cn.iocoder.yudao.module.wine.dal.dataobject.premiumrecord.PremiumRecordDO;
import cn.iocoder.yudao.module.wine.dal.dataobject.supplylabel.SupplyLabelDO;
import cn.iocoder.yudao.module.wine.dal.dataobject.supplymarket.SupplyMarketDO;
import cn.iocoder.yudao.module.wine.dal.dataobject.supplyorder.SupplyOrderDO;
import cn.iocoder.yudao.module.wine.dal.dataobject.supplyorderitem.SupplyOrderItemDO;
import cn.iocoder.yudao.module.wine.dal.dataobject.supplytype.SupplyTypeDO;
import cn.iocoder.yudao.module.wine.dal.mysql.businessuser.BusinessUserMapper;
import cn.iocoder.yudao.module.wine.dal.mysql.config.WineConfigMapper;
import cn.iocoder.yudao.module.wine.dal.mysql.countnameconfig.CountNameConfigMapper;
import cn.iocoder.yudao.module.wine.dal.mysql.premiumrecord.PremiumRecordMapper;
import cn.iocoder.yudao.module.wine.dal.mysql.supplylabel.SupplyLabelMapper;
import cn.iocoder.yudao.module.wine.dal.mysql.supplymarket.SupplyMarketMapper;
import cn.iocoder.yudao.module.wine.dal.mysql.supplyorder.SupplyOrderMapper;
import cn.iocoder.yudao.module.wine.dal.mysql.supplyorderitem.SupplyOrderItemMapper;
import cn.iocoder.yudao.module.wine.dal.mysql.supplytype.SupplyTypeMapper;
import cn.iocoder.yudao.module.wine.enums.AuditEnum;
import cn.iocoder.yudao.module.wine.enums.BusinessUserEnum;
import cn.iocoder.yudao.module.wine.service.messageboard.MessageBoardService;
import cn.iocoder.yudao.module.wine.service.supplyorderlog.SupplyOrderLogService;
import cn.iocoder.yudao.module.wine.utils.SnowflakeIdGeneratorUtil;
import cn.iocoder.yudao.module.wine.utils.WeChatUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import cn.iocoder.yudao.module.wine.controller.admin.supplyinfo.vo.*;
import cn.iocoder.yudao.module.wine.dal.dataobject.supplyinfo.SupplyInfoDO;
import cn.iocoder.yudao.module.wine.dal.mysql.supplyinfo.SupplyInfoMapper;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getTerminal;
import static cn.iocoder.yudao.module.wine.enums.ErrorCodeConstants.*;

/**
 * 供求信息 Service 实现类
 *
 * @author 管理员
 */
@Service
@Validated
@Slf4j
public class SupplyInfoServiceImpl implements SupplyInfoService {

    @Resource
    private SupplyInfoMapper supplyInfoMapper;

    @Resource
    private SupplyTypeMapper supplyTypeMapper;

    @Resource
    private SupplyOrderMapper supplyOrderMapper;

    @Resource
    private SupplyOrderLogService supplyOrderLogService;

    @Resource
    private PremiumRecordMapper premiumRecordMapper;

    @Resource
    private MemberUserApi memberUserApi;

    @Resource
    private BrokerageUserApi brokerageUserApi;

    @Resource
    private BusinessUserMapper businessUserMapper;

    @Resource
    private WineConfigMapper wineConfigMapper;

    @Resource
    private MessageBoardService messageBoardService;

    @Resource
    private SupplyLabelMapper supplyLabelMapper;

    @Resource
    private SupplyMarketMapper supplyMarketMapper;

    @Resource
    private SupplyOrderItemMapper supplyOrderItemMapper;

    @Resource
    private CountNameConfigMapper countNameConfigMapper;

    @Resource
    private DictDataApi dataApi;


    @Value("${wx.accessTokenUrl}")
    private String accessTokenUrl;

    @Value("${wx.unlimitedQRCodeUrl}")
    private String unlimitedQRCodeUrl;

    @Value("${wx.appid}")
    private String appid;

    @Value("${wx.appSecret}")
    private String appSecret;

    @Override
    public Long createSupplyInfo(SupplyInfoSaveReqVO createReqVO) {
        if (createReqVO.getRatio() != null) {
            if (createReqVO.getRatio() > 100 || createReqVO.getRatio() < 0) {
                throw exception(ILLEGAL_VALUE);
            }
        }
        // 插入
        SupplyInfoDO supplyInfo = BeanUtils.toBean(createReqVO, SupplyInfoDO.class);
        supplyInfo.setUserId(SecurityFrameworkUtils.getLoginUserId());
        List<WineConfigDO> wineConfigDOS = wineConfigMapper.selectList();
        WineConfigDO wineConfigDO = wineConfigDOS.get(0);
        if (wineConfigDO.getIsAudit().equals(ConfigEnum.NOT.getCode())) {
            supplyInfo.setStatus(SupplyInfoEnum.AUDIT.getCode());
        } else {
            supplyInfo.setStatus(SupplyInfoEnum.NO_AUDIT.getCode());
        }
        supplyInfoMapper.insert(supplyInfo);
        // 返回
        return supplyInfo.getId();
    }

    @Override
    public void updateSupplyInfo(SupplyInfoSaveReqVO updateReqVO) {
        if (updateReqVO.getRatio() != null) {
            if (updateReqVO.getRatio() > 100 || updateReqVO.getRatio() < 0) {
                throw exception(ILLEGAL_VALUE);
            }
        }
        // 校验存在
        validateSupplyInfoExists(updateReqVO.getId());
        // 更新
        SupplyInfoDO updateObj = BeanUtils.toBean(updateReqVO, SupplyInfoDO.class);
        supplyInfoMapper.updateById(updateObj);
    }

    @Override
    public void deleteSupplyInfo(Long id) {
        // 校验存在
        validateSupplyInfoExists(id);
        // 删除
        supplyInfoMapper.deleteById(id);
    }

    private SupplyInfoDO validateSupplyInfoExists(Long id) {
        SupplyInfoDO supplyInfoDO = supplyInfoMapper.selectById(id);
        if (supplyInfoDO == null) {
            throw exception(INFO_NOT_EXISTS);
        } else {
            return supplyInfoDO;
        }
    }

    @Override
    public SupplyInfoDO getSupplyInfo(Integer id) {
        return supplyInfoMapper.selectById(id);
    }

    @Override
    public PageResult<SupplyInfoRespVO> getSupplyInfoPage(SupplyInfoPageReqVO pageReqVO) {
        return supplyInfoMapper.selectPage(pageReqVO);
    }

    /**
     * 用户发布供求信息
     * @param createReqVO
     * @return
     */
    @Override
    public Integer appCreateSupplyInfo(AppSupplyInfoSaveReqVO createReqVO) {
        SupplyInfoDO supplyInfoDO = BeanUtils.toBean(createReqVO, SupplyInfoDO.class);
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        //查询会员信息
        MemberUserRespDTO user = memberUserApi.getUser(loginUserId);
        if (user == null) {
            throw exception(USER_NOT_EXISTS);
        }

        BusinessUserDO businessUserDO = authBusinessUser();

        supplyInfoDO.setUserId(loginUserId);

        //判断用户是否剩余发布条数
        Integer infoType = createReqVO.getInfoType();

        //参数配置
        List<WineConfigDO> wineConfigDOS = wineConfigMapper.selectList();
        WineConfigDO wineConfigDO = wineConfigDOS.get(0);
        if(wineConfigDO.getIsOpenUse()==1 && wineConfigDO.getFreeMonth()>0) {
            LocalDateTime createTime = user.getCreateTime();
            //获取下个月今天
            LocalDateTime plusMonthDateTime = createTime.plusMonths(wineConfigDO.getFreeMonth());
            if (plusMonthDateTime.isBefore(LocalDateTime.now())) {
                //判断可发布条数
                if (SupplyInfoEnum.ASK_TO_BUY.getCode().equals(infoType)) {
                    Integer buyNum = businessUserDO.getBuyNum();
                    //可发布数为0 抛出异常
                    if (buyNum.equals(0)) {
                        throw exception(COUNT_ZERO);
                    }
                    if (buyNum > 0) {
                        //可发布数减1
                        businessUserDO.setBuyNum(businessUserDO.getBuyNum() - 1);
                        businessUserMapper.updateById(businessUserDO);
                    }
                } else {
                    Integer supplyNum = businessUserDO.getSupplyNum();
                    //可发布数为0 抛出异常
                    if (supplyNum.equals(0)) {
                        throw exception(COUNT_ZERO);
                    }
                    if (supplyNum > 0) {
                        //可发布数减1
                        businessUserDO.setSupplyNum(businessUserDO.getSupplyNum() - 1);
                        businessUserMapper.updateById(businessUserDO);
                    }
                }
            }
        }
        //用户配置无需审核，配置要审核。则信息要审核
        //用户配置需要审核，配置不管怎么配置。信息都要审核
        if (AuditEnum.NO_AUDIT_REQUIRED.getCode().equals(user.getAudit())) {
            if (wineConfigDO.getIsAudit().equals(ConfigEnum.NOT.getCode())) {
                supplyInfoDO.setStatus(SupplyInfoEnum.AUDIT.getCode());
            } else {
                supplyInfoDO.setStatus(SupplyInfoEnum.NO_AUDIT.getCode());
            }
        } else {
            supplyInfoDO.setStatus(SupplyInfoEnum.NO_AUDIT.getCode());
        }

        if (supplyInfoDO.getPremiumRatio() == null) {
            supplyInfoDO.setPremiumRatio(wineConfigDO.getPremiumRatio());
        }
        if (!StringUtils.isEmpty(supplyInfoDO.getTags())) {
            String[] split = supplyInfoDO.getTags().split(",");
            List<String> list = Arrays.stream(split).collect(Collectors.toList());
            List<SupplyLabelDO> labelDOS = supplyLabelMapper.selectByNameListResponsibility(list);
            if (!CollectionUtil.isEmpty(labelDOS)) {
                supplyInfoDO.setIsDuty(SupplyInfoEnum.IS_DUTY.getCode());
            } else {
                supplyInfoDO.setIsDuty(SupplyInfoEnum.NO_DUTY.getCode());
            }
        } else {
            supplyInfoDO.setIsDuty(SupplyInfoEnum.NO_DUTY.getCode());
        }

        if (StringUtils.isEmpty(supplyInfoDO.getCountName())) {
            supplyInfoDO.setCountName(supplyInfoDO.getInfoTitle());
        }

        //判断该用户发布的供求信息是否可参与统计，是否有当前的配置
        supplyInfoDO.setIsConfig(0);
        supplyInfoDO.setIsCount(1);
        CountNameConfigDO countNameConfigDO = countNameConfigMapper.selectOne(new LambdaQueryWrapperX<CountNameConfigDO>()
                .eqIfPresent(CountNameConfigDO::getSupplyTypeId, supplyInfoDO.getSupplyTypeId())
                .eqIfPresent(CountNameConfigDO::getFragranceType, supplyInfoDO.getFragranceType())
                .eqIfPresent(CountNameConfigDO::getShowYear, supplyInfoDO.getShowYear())
                .eqIfPresent(CountNameConfigDO::getPacking, supplyInfoDO.getPacking())
                .likeIfPresent(CountNameConfigDO::getFailoverName, supplyInfoDO.getInfoTitle())
                .last("limit 1"));
        if(countNameConfigDO != null) {
            supplyInfoDO.setIsConfig(1);
            if (countNameConfigDO.getIsAudit() == 2) {
                supplyInfoDO.setIsCount(0);
            }
        }
        else{
            supplyInfoDO.setIsCount(0);
        }

        return supplyInfoMapper.insert(supplyInfoDO);
    }

    @Override
    public void appDeleteSupplyOrder(Long id) {
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        SupplyInfoDO supplyInfoDO = validateSupplyInfoExists(id);

        authBusinessUser();

        if (supplyInfoDO.getUserId().equals(loginUserId)) {
            supplyInfoMapper.deleteById(id);
        } else {
            throw exception(HAVE_NO_RIGHT_SUPPLY_INFO);
        }
    }

    @Override
    public void appUpdateSupplyInfo(SupplyInfoSaveReqVO updateReqVO) {
        SupplyInfoDO supplyInfoDO = BeanUtils.toBean(updateReqVO, SupplyInfoDO.class);
        SupplyInfoDO data = validateSupplyInfoExists(supplyInfoDO.getId());
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        MemberUserRespDTO user = memberUserApi.getUser(loginUserId);
        if (user == null) {
            throw exception(USER_NOT_EXISTS);
        }

        authBusinessUser();

        if (!data.getUserId().equals(loginUserId)) {
            throw exception(HAVE_NO_RIGHT_SUPPLY_INFO);
        }
        //判断该用户发布的内容是否需要审核
        List<WineConfigDO> wineConfigDOS = wineConfigMapper.selectList();
        WineConfigDO wineConfigDO = wineConfigDOS.get(0);

        //用户配置无需审核，配置要审核。则信息要审核
        //用户配置需要审核，配置不管怎么配置。信息都要审核
        if (AuditEnum.NO_AUDIT_REQUIRED.getCode().equals(user.getAudit())) {
            if (wineConfigDO.getIsAudit().equals(ConfigEnum.NOT.getCode())) {
                supplyInfoDO.setStatus(SupplyInfoEnum.AUDIT.getCode());
            } else {
                supplyInfoDO.setStatus(SupplyInfoEnum.NO_AUDIT.getCode());
            }
        } else {
            supplyInfoDO.setStatus(SupplyInfoEnum.NO_AUDIT.getCode());
        }

        if (StringUtils.isEmpty(supplyInfoDO.getCountName())) {
            supplyInfoDO.setCountName(supplyInfoDO.getInfoTitle());
        }
        //判断该用户发布的供求信息是否可参与统计，是否有当前的配置
        supplyInfoDO.setIsConfig(0);
        supplyInfoDO.setIsCount(1);
        CountNameConfigDO countNameConfigDO = countNameConfigMapper.selectOne(new LambdaQueryWrapperX<CountNameConfigDO>()
                .eqIfPresent(CountNameConfigDO::getSupplyTypeId, supplyInfoDO.getSupplyTypeId())
                .eqIfPresent(CountNameConfigDO::getFragranceType, supplyInfoDO.getFragranceType())
                .eqIfPresent(CountNameConfigDO::getShowYear, supplyInfoDO.getShowYear())
                .eqIfPresent(CountNameConfigDO::getPacking, supplyInfoDO.getPacking())
                .likeIfPresent(CountNameConfigDO::getFailoverName, supplyInfoDO.getInfoTitle())
                .last("limit 1"));
        if(countNameConfigDO!=null) {
            supplyInfoDO.setIsConfig(1);
            if (countNameConfigDO.getIsAudit() == 2) {
                supplyInfoDO.setIsCount(0);
            }
        }

        supplyInfoMapper.updateById(supplyInfoDO);
    }

    @Override
    public PageResult<SupplyInfoRespVO> selectList(AppSupplyInfoListReqVO reqVO) {
        if (reqVO.getSupplyTypeId() != null) {
            List<SupplyTypeDO> supplyTypeDOS = supplyTypeMapper.selectList(new LambdaQueryWrapperX<SupplyTypeDO>()
                    .eqIfPresent(SupplyTypeDO::getParentId, reqVO.getSupplyTypeId()));
            if (!CollectionUtil.isEmpty(supplyTypeDOS)){
                List<Integer> collect = supplyTypeDOS.stream().map(SupplyTypeDO::getId).collect(Collectors.toList());
                collect.add(reqVO.getSupplyTypeId());
                reqVO.setTypeIds(collect);
            }
        }
        PageResult<SupplyInfoRespVO> pageResult = supplyInfoMapper.selectList(reqVO);
        List<DictDataRespDTO> unit = dataApi.getDictDataList("unit");
        List<DictDataRespDTO> packing = dataApi.getDictDataList("packing");
        List<DictDataRespDTO> capacity = dataApi.getDictDataList("capacity");
        List<DictDataRespDTO> degree = dataApi.getDictDataList("degree");
        List<DictDataRespDTO> year = dataApi.getDictDataList("year");
        List<DictDataRespDTO> odorType = dataApi.getDictDataList("odor_type");
        List<DictDataRespDTO> language = dataApi.getDictDataList("language");
        List<DictDataRespDTO> producingArea = dataApi.getDictDataList("producing_area");
        if (!CollectionUtil.isEmpty(pageResult.getList())) {
            List<SupplyInfoRespVO> supplyInfoRespVOS = pageResult.getList();
            List<SupplyInfoRespVO> collect = supplyInfoRespVOS.stream().peek(item -> {
                unit.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getUnit()))) {
                        item.setUnitName(dict.getLabel());
                    }
                });
                packing.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getPacking()))) {
                        item.setPackingName(dict.getLabel());
                    }
                });
                capacity.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getCapacity()))) {
                        item.setCapacityName(dict.getLabel());
                    }
                });
                degree.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getDegree()))) {
                        item.setDegreeName(dict.getLabel());
                    }
                });
                year.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getShowYear()))) {
                        item.setShowYearName(dict.getLabel());
                    }
                });


                odorType.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getFragranceType()))) {
                        item.setFragranceTypeName(dict.getLabel());
                    }
                });
                language.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getLanguage()))) {
                        item.setLanguageName(dict.getLabel());
                    }
                });
                producingArea.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getProductArea()))) {
                        item.setProductAreaName(dict.getLabel());
                    }
                });
            }).collect(Collectors.toList());
            pageResult.setList(collect);
        }

        return pageResult;
    }

    @Override
    public List<SupplyInfoRespVO> selectMySupplyInfoList(AppSupplyInfoListReqVO reqVO) {
        if (reqVO.getSupplyTypeId() != null) {
            List<SupplyTypeDO> supplyTypeDOS = supplyTypeMapper.selectList(new LambdaQueryWrapperX<SupplyTypeDO>()
                    .eqIfPresent(SupplyTypeDO::getParentId, reqVO.getSupplyTypeId()));
            if (!CollectionUtil.isEmpty(supplyTypeDOS)){
                List<Integer> collect = supplyTypeDOS.stream().map(SupplyTypeDO::getId).collect(Collectors.toList());
                collect.add(reqVO.getSupplyTypeId());
                reqVO.setTypeIds(collect);
            }
        }
        List<SupplyInfoRespVO> supplyInfoRespVOS = supplyInfoMapper.selectMySupplyInfoList(reqVO);
        List<DictDataRespDTO> unit = dataApi.getDictDataList("unit");
        List<DictDataRespDTO> packing = dataApi.getDictDataList("packing");
        List<DictDataRespDTO> capacity = dataApi.getDictDataList("capacity");
        List<DictDataRespDTO> degree = dataApi.getDictDataList("degree");
        List<DictDataRespDTO> year = dataApi.getDictDataList("year");
        List<DictDataRespDTO> odorType = dataApi.getDictDataList("odor_type");
        List<DictDataRespDTO> language = dataApi.getDictDataList("language");
        List<DictDataRespDTO> producingArea = dataApi.getDictDataList("producing_area");
        if (!CollectionUtil.isEmpty(supplyInfoRespVOS)) {
            List<SupplyInfoRespVO> collect = supplyInfoRespVOS.stream().peek(item -> {
                String tags = item.getTags();
                if (!StringUtils.isEmpty(tags)) {
                    String[] split = item.getTags().split(",");
                    List<String> list = Arrays.stream(split).collect(Collectors.toList());
                    List<SupplyLabelDO> labelDOS = supplyLabelMapper.selectByNameList(list);
                    if (!CollectionUtil.isEmpty(labelDOS)) {
                        item.setIsGuarantee(SupplyInfoEnum.IS_GUARANTEE.getCode());
                    } else {
                        item.setIsGuarantee(SupplyInfoEnum.NOT_GUARANTEE.getCode());
                    }
                } else {
                    item.setIsGuarantee(SupplyInfoEnum.NOT_GUARANTEE.getCode());
                }
                unit.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getUnit()))) {
                        item.setUnitName(dict.getLabel());
                    }
                });
                packing.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getPacking()))) {
                        item.setPackingName(dict.getLabel());
                    }
                });
                capacity.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getCapacity()))) {
                        item.setCapacityName(dict.getLabel());
                    }
                });
                degree.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getDegree()))) {
                        item.setDegreeName(dict.getLabel());
                    }
                });
                year.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getShowYear()))) {
                        item.setShowYearName(dict.getLabel());
                    }
                });
                odorType.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getFragranceType()))) {
                        item.setFragranceTypeName(dict.getLabel());
                    }
                });
                language.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getLanguage()))) {
                        item.setLanguageName(dict.getLabel());
                    }
                });
                producingArea.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getProductArea()))) {
                        item.setProductAreaName(dict.getLabel());
                    }
                });
            }).collect(Collectors.toList());
            return collect;
        }
        return supplyInfoRespVOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SupplyInfoRespVO appGetSupplyInfoData(Long id) {
        SupplyInfoRespVO data = supplyInfoMapper.appGetSupplyInfoData(id);
        if (data != null) {
            // 设置是否收藏状态
            if (data.getFavoriteId() != null) {
                data.setIsFavorite(SupplyInfoEnum.FAVORITE.getCode());
            } else {
                data.setIsFavorite(SupplyInfoEnum.NOT_FAVORITE.getCode());
            }
            // 关注状态为空，设置未关注状态
            if (data.getSubscribeStatus() == null) {
                data.setSubscribeStatus(UserFansSubscribeEnum.UNFOLLOW.getStatus());
            }
            //  设置浏览量
            if (!data.getUserId().equals(SecurityFrameworkUtils.getLoginUserId())) {
                data.setViewCount(data.getViewCount() + 1);
            }
            SupplyInfoDO supplyInfoDO = BeanUtils.toBean(data, SupplyInfoDO.class);
            supplyInfoMapper.updateById(supplyInfoDO);
            if (!StringUtils.isEmpty(data.getTags())) {
                String[] split = data.getTags().split(",");
                List<String> list = Arrays.stream(split).collect(Collectors.toList());
                List<SupplyLabelDO> labelDOS = supplyLabelMapper.selectByNameList(list);
                if (!CollectionUtil.isEmpty(labelDOS)) {
                    data.setIsGuarantee(SupplyInfoEnum.IS_GUARANTEE.getCode());
                } else {
                    data.setIsGuarantee(SupplyInfoEnum.NOT_GUARANTEE.getCode());
                }
            } else {
                data.setIsGuarantee(SupplyInfoEnum.NOT_GUARANTEE.getCode());
            }
            List<DictDataRespDTO> unit = dataApi.getDictDataList("unit");
            List<DictDataRespDTO> packing = dataApi.getDictDataList("packing");
            List<DictDataRespDTO> capacity = dataApi.getDictDataList("capacity");
            List<DictDataRespDTO> degree = dataApi.getDictDataList("degree");
            List<DictDataRespDTO> year = dataApi.getDictDataList("year");
            List<DictDataRespDTO> odorType = dataApi.getDictDataList("odor_type");
            List<DictDataRespDTO> language = dataApi.getDictDataList("language");
            List<DictDataRespDTO> producingArea = dataApi.getDictDataList("producing_area");
            unit.forEach(dict -> {
                if (dict.getValue().equals(String.valueOf(data.getUnit()))) {
                    data.setUnitName(dict.getLabel());
                }
            });
            packing.forEach(dict -> {
                if (dict.getValue().equals(String.valueOf(data.getPacking()))) {
                    data.setPackingName(dict.getLabel());
                }
            });
            capacity.forEach(dict -> {
                if (dict.getValue().equals(String.valueOf(data.getCapacity()))) {
                    data.setCapacityName(dict.getLabel());
                }
            });
            degree.forEach(dict -> {
                if (dict.getValue().equals(String.valueOf(data.getDegree()))) {
                    data.setDegreeName(dict.getLabel());
                }
            });
            year.forEach(dict -> {
                if (dict.getValue().equals(String.valueOf(data.getShowYear()))) {
                    data.setShowYearName(dict.getLabel());
                }
            });
            odorType.forEach(dict -> {
                if (dict.getValue().equals(String.valueOf(data.getFragranceType()))) {
                    data.setFragranceTypeName(dict.getLabel());
                }
            });
            language.forEach(dict -> {
                if (dict.getValue().equals(String.valueOf(data.getLanguage()))) {
                    data.setLanguageName(dict.getLabel());
                }
            });
            producingArea.forEach(dict -> {
                if (dict.getValue().equals(String.valueOf(data.getProductArea()))) {
                    data.setProductAreaName(dict.getLabel());
                }
            });
        }

        return data;
    }

    /**
     * 生成担保、担责担保订单
     * @param reqVO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean guaranteeSupplyInfo(AppCreateOrderReqVO reqVO) {
        List<AppSupplyInfoItemReqVO> supplyInfoData = reqVO.getSupplyInfoData();
        if (CollectionUtil.isEmpty(supplyInfoData)) {
            throw exception(SUPPLY_AND_DEMAND_INFORMATION_NULL);
        }

        String saleUserMobile = reqVO.getSaleUserMobile();
        MemberUserRespDTO saleUser = memberUserApi.getUserByMobile(saleUserMobile);

        String buyUserMobile = reqVO.getBuyUserMobile();
        MemberUserRespDTO buyUser = memberUserApi.getUserByMobile(buyUserMobile);

        // 创建订单
        SupplyOrderDO supplyOrderDO = new SupplyOrderDO();
        //雪花算法 ->订单号
        String orderNo = SnowflakeIdGeneratorUtil.generateId();
        //订单号
        supplyOrderDO.setNo(orderNo);

        supplyOrderDO.setTerminal(getTerminal());

        if (saleUser == null || buyUser == null) {
            throw exception(INFORMATION_ERROR);
        }
        //买方用户id
        supplyOrderDO.setBuyUserId(buyUser.getId());
        //卖方用户id
        supplyOrderDO.setSaleUserId(saleUser.getId());
        //推广人id
        BrokerageUserDTO brokerageUserDTO = brokerageUserApi.getBindUserId(saleUser.getId());
        Long bindUserId = brokerageUserDTO.getBindUserId();
        supplyOrderDO.setBrokerageUserId(bindUserId);

        BigDecimal bigDecimal = new BigDecimal(100);
        //设置地址
        supplyOrderDO.setReceiverName(reqVO.getBuyUserName());
        supplyOrderDO.setReceiverMobile(reqVO.getBuyUserMobile());
        supplyOrderDO.setReceiverCompanyName(reqVO.getBuyCompanyName());
        supplyOrderDO.setReceiverDetailAddress(reqVO.getReceiveAddress());

        //上传信息
        supplyOrderDO.setLogisticsId(reqVO.getLogisticsId());
        supplyOrderDO.setLogisticsNo(reqVO.getLogisticsNo());
        supplyOrderDO.setDeliveryImages(reqVO.getDeliveryImages());
        supplyOrderDO.setDeliveryVideo(reqVO.getDeliveryVideo());

        supplyOrderDO.setSalesLogisticsNo(reqVO.getSalesLogisticsNo());
        supplyOrderDO.setSalesImages(reqVO.getSalesImages());

        //后台操作状态
        if (reqVO.getOperateStatus() != null) {
            supplyOrderDO.setOperateStatus(reqVO.getOperateStatus());
        }

        supplyOrderMapper.insert(supplyOrderDO);

        //创建供求订单项列表
        for (int z = 0; z < supplyInfoData.size(); z++) {

            SupplyInfoDO supplyInfoDO = supplyInfoMapper.selectOne(new LambdaQueryWrapperX<SupplyInfoDO>().eq(SupplyInfoDO::getId, supplyInfoData.get(z).getSupplyInfoId()));
            if (!SupplyInfoEnum.NO_TRADE.getCode().equals(supplyInfoDO.getTradeStatus())) {
                throw exception(IN_TRADING);
            }
            if (!StringUtils.isEmpty(reqVO.getClause())) {
                supplyInfoDO.setClause(reqVO.getClause());
            }
            //修改供求信息交易状态为 担保交易中或担保担责交易中
            if (SupplyInfoEnum.IS_DUTY.getCode().equals(supplyInfoDO.getIsDuty())) {
                supplyInfoDO.setTradeStatus(SupplyInfoEnum.TAKE_RESPONSIBILITY_FOR_SECURED_TRANSACTIONS.getCode());
            } else {
                supplyInfoDO.setTradeStatus(SupplyInfoEnum.SECURED_TRANSACTION.getCode());
            }
            //变更供求信息:减数量、改价格
            supplyInfoDO.setPackages(supplyInfoData.get(z).getPackages() == null ? supplyInfoDO.getPackages() : supplyInfoData.get(z).getPackages());
            supplyInfoDO.setSalePrice(supplyInfoData.get(z).getSalePrice() == null ? supplyInfoDO.getSalePrice() : supplyInfoData.get(z).getSalePrice());
            supplyInfoMapper.updateById(supplyInfoDO);

            //创建供求订单项信息
            BigDecimal multiply = supplyInfoDO.getSalePrice().multiply(new BigDecimal(supplyInfoDO.getPackages())).multiply(new BigDecimal(supplyInfoDO.getQuantity()));

            //保费金额
            BigDecimal premiumRatio = supplyInfoDO.getPremiumRatio();
            BigDecimal ratio = premiumRatio.divide(bigDecimal, 3, RoundingMode.HALF_UP);

            SupplyOrderItemDO supplyOrderItemDO = new SupplyOrderItemDO();
            supplyOrderItemDO.setPackages(supplyInfoDO.getPackages());
            supplyOrderItemDO.setPremiumPrice(ratio.multiply(multiply).setScale(2, RoundingMode.HALF_UP).multiply(bigDecimal).intValue());
            supplyOrderItemDO.setPayPrice(multiply);
            supplyOrderItemDO.setSalePrice(supplyInfoDO.getSalePrice());
            supplyOrderItemDO.setOrderId(supplyOrderDO.getId());
            supplyOrderItemDO.setInfoId(supplyInfoDO.getId());
            supplyOrderItemDO.setQuantity(supplyInfoDO.getQuantity());
            supplyOrderItemMapper.insert(supplyOrderItemDO);
            //订单类型 出售，求购，套现
            supplyOrderDO.setType(supplyInfoDO.getInfoType());
            //交易类型
            supplyOrderDO.setTradeType(supplyInfoDO.getTradeStatus());
        }

        List<SupplyOrderItemDO> list = supplyOrderItemMapper.getSupplyOrderItemListByOrderId(supplyOrderDO.getId());
        BigDecimal price = list.stream().map(SupplyOrderItemDO::getPayPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
        Integer premiumPrice = list.stream().map(SupplyOrderItemDO::getPremiumPrice).reduce(0, Integer::sum);

        Integer packages = list.stream().map(SupplyOrderItemDO::getPackages).reduce(0, Integer::sum);
        Integer quantity = list.stream().map(SupplyOrderItemDO::getQuantity).reduce(0, Integer::sum);
        //购买总数量
        supplyOrderDO.setProductCount(packages);
        supplyOrderDO.setProductQuantity(quantity);

        //商品原价 单位分 所以要*100
        supplyOrderDO.setTotalPrice(price.multiply(bigDecimal).intValue());
        //应付金额（总），单位：分
        supplyOrderDO.setPayPrice(price.multiply(bigDecimal).intValue());
        supplyOrderDO.setPremiumPrice(premiumPrice);
        supplyOrderMapper.updateById(supplyOrderDO);

        //买家 卖家 保费信息
        if (premiumPrice != 0) {
            BigDecimal divide = new BigDecimal(premiumPrice).divide(bigDecimal, 2, RoundingMode.HALF_UP);
            PremiumRecordDO buyUserRecordDO = new PremiumRecordDO();
            buyUserRecordDO.setPremium(divide);
            buyUserRecordDO.setOrderId(supplyOrderDO.getId());
            buyUserRecordDO.setCreateTime(LocalDateTime.now());
            buyUserRecordDO.setUserId(buyUser.getId());
            int i = premiumRecordMapper.insert(buyUserRecordDO);

            PremiumRecordDO saleUserRecordDO = new PremiumRecordDO();
            saleUserRecordDO.setPremium(divide);
            saleUserRecordDO.setOrderId(supplyOrderDO.getId());
            saleUserRecordDO.setCreateTime(LocalDateTime.now());
            saleUserRecordDO.setUserId(saleUser.getId());
            int j = premiumRecordMapper.insert(saleUserRecordDO);
        }

        //记录日志订单日志
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        if (loginUserId == null) {
            throw exception(NOT_LOGIN);
        }
        if (loginUserId.equals(buyUser.getId())) {
            supplyOrderLogService.logRecord(loginUserId, supplyOrderDO.getId(),
                    UserTypeEnum.MEMBER.getName(), SupplyOrderLogEnum.BUYER_SUBMISSION_OF_SECURITY_AGREEMENT.getContent());
        }
        if (loginUserId.equals(saleUser.getId())) {
            supplyOrderLogService.logRecord(loginUserId, supplyOrderDO.getId(),
                    UserTypeEnum.MEMBER.getName(), SupplyOrderLogEnum.SELLER_SUBMISSION_OF_SECURITY_AGREEMENT.getContent());
        }
        sendMessage(saleUser.getId(), buyUser.getId());

        return true;
    }

    @Override
    public List<SupplyInfoRespVO> appGetSupplyInfoDataList(Long[] ids) {
        List<SupplyInfoRespVO> supplyInfoRespVOS = supplyInfoMapper.selectJoinList(SupplyInfoRespVO.class, new MPJLambdaWrapperX<SupplyInfoDO>()
                .inIfPresent(SupplyInfoDO::getId, ids));

        List<DictDataRespDTO> unit = dataApi.getDictDataList("unit");
        List<DictDataRespDTO> packing = dataApi.getDictDataList("packing");
        List<DictDataRespDTO> capacity = dataApi.getDictDataList("capacity");
        List<DictDataRespDTO> degree = dataApi.getDictDataList("degree");
        List<DictDataRespDTO> year = dataApi.getDictDataList("year");
        List<DictDataRespDTO> odorType = dataApi.getDictDataList("odor_type");
        List<DictDataRespDTO> language = dataApi.getDictDataList("language");
        List<DictDataRespDTO> producingArea = dataApi.getDictDataList("producing_area");
        if (!CollectionUtil.isEmpty(supplyInfoRespVOS)) {
            List<SupplyInfoRespVO> collect = supplyInfoRespVOS.stream().peek(item -> {
                unit.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getUnit()))) {
                        item.setUnitName(dict.getLabel());
                    }
                });
                packing.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getPacking()))) {
                        item.setPackingName(dict.getLabel());
                    }
                });
                capacity.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getCapacity()))) {
                        item.setCapacityName(dict.getLabel());
                    }
                });
                degree.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getDegree()))) {
                        item.setDegreeName(dict.getLabel());
                    }
                });
                year.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getShowYear()))) {
                        item.setShowYearName(dict.getLabel());
                    }
                });
                odorType.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getFragranceType()))) {
                        item.setFragranceTypeName(dict.getLabel());
                    }
                });
                language.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getLanguage()))) {
                        item.setLanguageName(dict.getLabel());
                    }
                });
                producingArea.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getProductArea()))) {
                        item.setProductAreaName(dict.getLabel());
                    }
                });
            }).collect(Collectors.toList());
            return collect;
        }
        return supplyInfoRespVOS;
    }


    @Override
    public List<SupplyInfoRespVO> getMarketSupplyInfoList(AppMarketReqVO reqVO) {
        List<SupplyInfoRespVO> supplyInfoRespVOS = supplyInfoMapper.getMarketSupplyInfoList(reqVO);
        return supplyInfoRespVOS;

    }

    @Override
    public List<SupplyInfoRespVO> getUserSupplyInfoList(AppSupplyInfoListReqVO reqVO) {
        List<SupplyInfoRespVO> supplyInfoRespVOS = supplyInfoMapper.getUserSupplyInfoList(reqVO);

        List<DictDataRespDTO> unit = dataApi.getDictDataList("unit");
        List<DictDataRespDTO> packing = dataApi.getDictDataList("packing");
        List<DictDataRespDTO> capacity = dataApi.getDictDataList("capacity");
        List<DictDataRespDTO> degree = dataApi.getDictDataList("degree");
        List<DictDataRespDTO> year = dataApi.getDictDataList("year");
        List<DictDataRespDTO> odorType = dataApi.getDictDataList("odor_type");
        List<DictDataRespDTO> language = dataApi.getDictDataList("language");
        List<DictDataRespDTO> producingArea = dataApi.getDictDataList("producing_area");
        if (!CollectionUtil.isEmpty(supplyInfoRespVOS)) {
            List<SupplyInfoRespVO> collect = supplyInfoRespVOS.stream().peek(item -> {
                String tags = item.getTags();
                if (!StringUtils.isEmpty(tags)) {
                    String[] split = item.getTags().split(",");
                    List<String> list = Arrays.stream(split).collect(Collectors.toList());
                    List<SupplyLabelDO> labelDOS = supplyLabelMapper.selectByNameList(list);
                    if (!CollectionUtil.isEmpty(labelDOS)) {
                        item.setIsGuarantee(SupplyInfoEnum.IS_GUARANTEE.getCode());
                    } else {
                        item.setIsGuarantee(SupplyInfoEnum.NOT_GUARANTEE.getCode());
                    }
                } else {
                    item.setIsGuarantee(SupplyInfoEnum.NOT_GUARANTEE.getCode());
                }
                unit.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getUnit()))) {
                        item.setUnitName(dict.getLabel());
                    }
                });
                packing.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getPacking()))) {
                        item.setPackingName(dict.getLabel());
                    }
                });
                capacity.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getCapacity()))) {
                        item.setCapacityName(dict.getLabel());
                    }
                });
                degree.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getDegree()))) {
                        item.setDegreeName(dict.getLabel());
                    }
                });
                year.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getShowYear()))) {
                        item.setShowYearName(dict.getLabel());
                    }
                });
                odorType.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getFragranceType()))) {
                        item.setFragranceTypeName(dict.getLabel());
                    }
                });
                language.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getLanguage()))) {
                        item.setLanguageName(dict.getLabel());
                    }
                });
                producingArea.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getProductArea()))) {
                        item.setProductAreaName(dict.getLabel());
                    }
                });
            }).collect(Collectors.toList());
            return collect;
        }
        return supplyInfoRespVOS;

    }
    @Override
    public List<SupplyInfoRespVO> getUserSupplyShareList(AppSupplyInfoListReqVO reqVO) {
        List<SupplyInfoRespVO> supplyInfoRespVOS = supplyInfoMapper.getUserSupplyShareList(reqVO);

        List<DictDataRespDTO> unit = dataApi.getDictDataList("unit");
        List<DictDataRespDTO> packing = dataApi.getDictDataList("packing");
        List<DictDataRespDTO> capacity = dataApi.getDictDataList("capacity");
        List<DictDataRespDTO> degree = dataApi.getDictDataList("degree");
        List<DictDataRespDTO> year = dataApi.getDictDataList("year");
        List<DictDataRespDTO> odorType = dataApi.getDictDataList("odor_type");
        List<DictDataRespDTO> language = dataApi.getDictDataList("language");
        List<DictDataRespDTO> producingArea = dataApi.getDictDataList("producing_area");
        if (!CollectionUtil.isEmpty(supplyInfoRespVOS)) {
            List<SupplyInfoRespVO> collect = supplyInfoRespVOS.stream().peek(item -> {
                String tags = item.getTags();
                if (!StringUtils.isEmpty(tags)) {
                    String[] split = item.getTags().split(",");
                    List<String> list = Arrays.stream(split).collect(Collectors.toList());
                    List<SupplyLabelDO> labelDOS = supplyLabelMapper.selectByNameList(list);
                    if (!CollectionUtil.isEmpty(labelDOS)) {
                        item.setIsGuarantee(SupplyInfoEnum.IS_GUARANTEE.getCode());
                    } else {
                        item.setIsGuarantee(SupplyInfoEnum.NOT_GUARANTEE.getCode());
                    }
                } else {
                    item.setIsGuarantee(SupplyInfoEnum.NOT_GUARANTEE.getCode());
                }
                unit.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getUnit()))) {
                        item.setUnitName(dict.getLabel());
                    }
                });
                packing.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getPacking()))) {
                        item.setPackingName(dict.getLabel());
                    }
                });
                capacity.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getCapacity()))) {
                        item.setCapacityName(dict.getLabel());
                    }
                });
                degree.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getDegree()))) {
                        item.setDegreeName(dict.getLabel());
                    }
                });
                year.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getShowYear()))) {
                        item.setShowYearName(dict.getLabel());
                    }
                });
                odorType.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getFragranceType()))) {
                        item.setFragranceTypeName(dict.getLabel());
                    }
                });
                language.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getLanguage()))) {
                        item.setLanguageName(dict.getLabel());
                    }
                });
                producingArea.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getProductArea()))) {
                        item.setProductAreaName(dict.getLabel());
                    }
                });
            }).collect(Collectors.toList());
            return collect;
        }
        return supplyInfoRespVOS;

    }

    @Override
    public PageResult<SupplyInfoRespVO> appGetSupplyMarketInfoList(MarketInfoListPageReqVO reqVo) {

        CountNameConfigDO countNameConfigDO = countNameConfigMapper.selectOne(new LambdaQueryWrapperX<CountNameConfigDO>()
                .eqIfPresent(CountNameConfigDO::getId, reqVo.getInfoId())
                .eqIfPresent(CountNameConfigDO::getCountName, reqVo.getInfoNme())
                .eqIfPresent(CountNameConfigDO::getPacking, reqVo.getPacking())
                .eqIfPresent(CountNameConfigDO::getShowYear, reqVo.getShowYear())
                .eq(CountNameConfigDO::getDeleted,0)
                .last("limit 1"));

        if (countNameConfigDO != null) {

            List<Integer> areaList = new ArrayList<>();
            if (reqVo.getAreaId() != null){
                Integer areaId = reqVo.getAreaId();
                Area area = AreaUtils.getArea(areaId);
                if(area.getType().equals(AreaTypeEnum.PROVINCE.getType())){
                    List<Area> children = area.getChildren();
                    List<Integer> collect = children.stream().map(item -> item.getId()).collect(Collectors.toList());
                    collect.forEach(item -> {
                        Area area1 = AreaUtils.getArea(item);
                        List<Integer> collect1 = area1.getChildren().stream().map(data -> data.getId()).collect(Collectors.toList());
                        areaList.addAll(collect1);
                    });
                    areaList.addAll(collect);
                }
                if (area.getType().equals(AreaTypeEnum.CITY.getType())){
                    List<Area> children = area.getChildren();
                    List<Integer> collect = children.stream().map(item -> item.getId()).collect(Collectors.toList());
                    areaList.addAll(collect);
                }
            }

            String countName = countNameConfigDO.getCountName();
            String failoverName = countNameConfigDO.getFailoverName();
            String name = countName + "," + failoverName;
            String[] strings = name.split(",");

            PageResult<SupplyInfoRespVO> appSupplyInfoListRespVOS = supplyInfoMapper.selectJoinPage(reqVo,SupplyInfoRespVO.class, new MPJLambdaWrapperX<SupplyInfoDO>()
                        .inIfPresent(SupplyInfoDO::getCountName, strings)
                        .eqIfPresent(SupplyInfoDO::getSupplyTypeId,countNameConfigDO.getSupplyTypeId())
                        .eqIfPresent(SupplyInfoDO::getFragranceType,countNameConfigDO.getFragranceType())
                        .eqIfPresent(SupplyInfoDO::getShowYear,countNameConfigDO.getShowYear())
                        .eqIfPresent(SupplyInfoDO::getPacking,countNameConfigDO.getPacking())
                        .eqIfPresent(SupplyInfoDO::getStatus, SupplyInfoEnum.AUDIT.getCode())//审核后才能显示
                        .eqIfPresent(SupplyInfoDO::getIsCount,1)

                    .leftJoin(BusinessUserDO.class, BusinessUserDO::getUserId, SupplyInfoDO::getUserId)
                    .in(!CollectionUtil.isEmpty(areaList),BusinessUserDO::getAreaId,areaList)
                    .selectAll(SupplyInfoDO.class)
                    .selectAs(BusinessUserDO::getAreaId, SupplyInfoRespVO::getAreaId)
                    .eq(SupplyInfoDO::getInfoType, reqVo.getType())
                    .eq(SupplyInfoDO::getShowYear, reqVo.getShowYear())
                    .orderByDesc(SupplyInfoDO::getCreateTime));

            List<DictDataRespDTO> unit = dataApi.getDictDataList("unit");
            List<SupplyInfoRespVO> list = appSupplyInfoListRespVOS.getList();
            if (!CollectionUtil.isEmpty(list)) {
                List<SupplyInfoRespVO> collect = list.stream().peek(item -> {
                    String format = AreaUtils.format(item.getAreaId(), " ");
                    item.setAreaName(format);
                    unit.forEach(dict -> {
                        if (dict.getValue().equals(String.valueOf(item.getUnit()))) {
                            item.setUnitName(dict.getLabel());
                        }
                    });
                }).collect(Collectors.toList());
                appSupplyInfoListRespVOS.setList(collect);
            }
            return appSupplyInfoListRespVOS;
        }
        return null;
    }


    /**
     * 原来写的有问题的代码，后期删除
     * @param reqVo
     * @return
     */
    public PageResult<SupplyInfoRespVO> appGetSupplyMarketInfoOldList(MarketInfoListPageReqVO reqVo) {
        SupplyMarketDO supplyMarketDO = supplyMarketMapper.selectOne(new LambdaQueryWrapperX<SupplyMarketDO>()
                .eqIfPresent(SupplyMarketDO::getInfoNme, reqVo.getInfoNme())
                .eqIfPresent(SupplyMarketDO::getPacking, reqVo.getPacking())
                .eqIfPresent(SupplyMarketDO::getShowYear, reqVo.getShowYear())
                .orderByDesc(SupplyMarketDO::getCreateTime)
                .last("limit 1"));

        if (supplyMarketDO != null) {
            List<Integer> areaList = new ArrayList<>();
            if (reqVo.getAreaId() != null){
                Integer areaId = reqVo.getAreaId();
                Area area = AreaUtils.getArea(areaId);
                if(area.getType().equals(AreaTypeEnum.PROVINCE.getType())){
                    List<Area> children = area.getChildren();
                    List<Integer> collect = children.stream().map(item -> item.getId()).collect(Collectors.toList());
                    collect.forEach(item -> {
                        Area area1 = AreaUtils.getArea(item);
                        List<Integer> collect1 = area1.getChildren().stream().map(data -> data.getId()).collect(Collectors.toList());
                        areaList.addAll(collect1);
                    });
                    areaList.addAll(collect);
                }
                if (area.getType().equals(AreaTypeEnum.CITY.getType())){
                    List<Area> children = area.getChildren();
                    List<Integer> collect = children.stream().map(item -> item.getId()).collect(Collectors.toList());
                    areaList.addAll(collect);
                }
            }
//            LocalDateTime createTime = supplyMarketDO.getCreateTime();
//            LocalDateTime dateTime = createTime.minusDays(1);

            PageResult<SupplyInfoRespVO> appSupplyInfoListRespVOS = supplyInfoMapper.selectJoinPage(reqVo,SupplyInfoRespVO.class, new MPJLambdaWrapperX<SupplyInfoDO>()
//                  .betweenIfPresent(SupplyInfoDO::getCreateTime, dateTime, createTime)
                    .eq(SupplyInfoDO::getSupplyTypeId,supplyMarketDO.getSupplyTypeId())
                    .eq(SupplyInfoDO::getFragranceType,supplyMarketDO.getFragranceType())
                    .eq(SupplyInfoDO::getShowYear,supplyMarketDO.getShowYear())
                    .eq(SupplyInfoDO::getPacking,supplyMarketDO.getPacking())
                    .eq(SupplyInfoDO::getStatus, SupplyInfoEnum.AUDIT.getCode())//审核后才能显示
                    .eq(SupplyInfoDO::getIsCount,1)

                    .leftJoin(BusinessUserDO.class, BusinessUserDO::getUserId, SupplyInfoDO::getUserId)
                    .in(!CollectionUtil.isEmpty(areaList),BusinessUserDO::getAreaId,areaList)
                    .selectAll(SupplyInfoDO.class)
                    .selectAs(BusinessUserDO::getAreaId, SupplyInfoRespVO::getAreaId)
                    .eq(SupplyInfoDO::getInfoType, reqVo.getType())
                    .eq(SupplyInfoDO::getShowYear, reqVo.getShowYear())
                    .orderByDesc(SupplyInfoDO::getCreateTime));

            List<DictDataRespDTO> unit = dataApi.getDictDataList("unit");
            List<SupplyInfoRespVO> list = appSupplyInfoListRespVOS.getList();
            if (!CollectionUtil.isEmpty(list)) {
                List<SupplyInfoRespVO> collect = list.stream().peek(item -> {
                    String format = AreaUtils.format(item.getAreaId(), " ");
                    item.setAreaName(format);
                    unit.forEach(dict -> {
                        if (dict.getValue().equals(String.valueOf(item.getUnit()))) {
                            item.setUnitName(dict.getLabel());
                        }
                    });
                }).collect(Collectors.toList());
                appSupplyInfoListRespVOS.setList(collect);
            }
            return appSupplyInfoListRespVOS;
        }
        return null;
    }

    @Override
    public void updateSupplyInfoStatus(SupplyInfoSaveReqVO updateReqVO) {
        SupplyInfoDO supplyInfoDO = BeanUtils.toBean(updateReqVO, SupplyInfoDO.class);
        validateSupplyInfoExists(supplyInfoDO.getId());
        supplyInfoMapper.updateById(supplyInfoDO);
    }

    @Override
    public List<SupplyInfoDO> getSupplyInfoByDay(CountNameConfigDO countNameConfigDO) {
        // 获取今天的日期
        // 获取当前的日期时间
        LocalDateTime now = LocalDateTime.now();

        // 设置时间为今天的 0 时 0 分 0 秒
        LocalDateTime todayStart = LocalDateTime.of(now.toLocalDate(), LocalTime.of(0, 0, 0));

        // 将今天的日期和0点时间组合
        LocalDateTime dateTime = todayStart.minusDays(1L);

        String countName = countNameConfigDO.getCountName();
        String failoverName = countNameConfigDO.getFailoverName();
        String name = countName + "," + failoverName;
        String[] strings = name.split(",");
        return supplyInfoMapper.selectList(new LambdaQueryWrapperX<SupplyInfoDO>()
                .eqIfPresent(SupplyInfoDO::getSupplyTypeId, countNameConfigDO.getSupplyTypeId())
                .eqIfPresent(SupplyInfoDO::getFragranceType, countNameConfigDO.getFragranceType())
                .eqIfPresent(SupplyInfoDO::getShowYear, countNameConfigDO.getShowYear())
                .eqIfPresent(SupplyInfoDO::getPacking, countNameConfigDO.getPacking())
                .inIfPresent(SupplyInfoDO::getCountName, strings)
                .le(SupplyInfoDO::getCreateTime,todayStart)
                .ge(SupplyInfoDO::getCreateTime, dateTime)
                .orderByDesc(SupplyInfoDO::getCreateTime));
    }

    @Override
    public List<SupplyInfoRespVO> getHomePageSupplyInfoList(AppSupplyInfoListReqVO reqVO) {
        List<SupplyInfoRespVO> supplyInfoRespVOS = supplyInfoMapper.getHomePageSupplyInfoList(reqVO);
        List<DictDataRespDTO> unit = dataApi.getDictDataList("unit");
        List<DictDataRespDTO> packing = dataApi.getDictDataList("packing");
        List<DictDataRespDTO> capacity = dataApi.getDictDataList("capacity");
        List<DictDataRespDTO> degree = dataApi.getDictDataList("degree");
        List<DictDataRespDTO> year = dataApi.getDictDataList("year");
        List<DictDataRespDTO> odorType = dataApi.getDictDataList("odor_type");
        List<DictDataRespDTO> language = dataApi.getDictDataList("language");
        List<DictDataRespDTO> producingArea = dataApi.getDictDataList("producing_area");
        if (!CollectionUtil.isEmpty(supplyInfoRespVOS)) {
            List<SupplyInfoRespVO> collect = supplyInfoRespVOS.stream().peek(item -> {
                unit.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getUnit()))) {
                        item.setUnitName(dict.getLabel());
                    }
                });
                packing.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getPacking()))) {
                        item.setPackingName(dict.getLabel());
                    }
                });
                capacity.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getCapacity()))) {
                        item.setCapacityName(dict.getLabel());
                    }
                });
                degree.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getDegree()))) {
                        item.setDegreeName(dict.getLabel());
                    }
                });
                year.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getShowYear()))) {
                        item.setShowYearName(dict.getLabel());
                    }
                });


                odorType.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getFragranceType()))) {
                        item.setFragranceTypeName(dict.getLabel());
                    }
                });
                language.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getLanguage()))) {
                        item.setLanguageName(dict.getLabel());
                    }
                });
                producingArea.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getProductArea()))) {
                        item.setProductAreaName(dict.getLabel());
                    }
                });
            }).collect(Collectors.toList());
            return collect;
        }
        return supplyInfoRespVOS;

    }

    @Override
    public PageResult<SupplyInfoRespVO> appGetSupplyMarketInfoPage(InfoPageReqVO reqVO) {
        CountNameConfigDO countNameConfigDO = countNameConfigMapper.selectOne(new LambdaQueryWrapperX<CountNameConfigDO>()
                .eqIfPresent(CountNameConfigDO::getCountName, reqVO.getInfoNme())
                .last("limit 1"));

        String countName = countNameConfigDO.getCountName();
        String failoverName = countNameConfigDO.getFailoverName();
        String name = countName + "," + failoverName;
        String[] strings = name.split(",");
        List<Integer> areaList = new ArrayList<>();
        if (reqVO.getAreaId() != null){
            Integer areaId = reqVO.getAreaId();
            Area area = AreaUtils.getArea(areaId);
            if(area.getType().equals(AreaTypeEnum.PROVINCE.getType())){
                List<Area> children = area.getChildren();
                List<Integer> collect = children.stream().map(item -> item.getId()).collect(Collectors.toList());
                collect.forEach(item -> {
                    Area area1 = AreaUtils.getArea(item);
                    List<Integer> collect1 = area1.getChildren().stream().map(data -> data.getId()).collect(Collectors.toList());
                    areaList.addAll(collect1);
                });
                areaList.addAll(collect);
            }
            if (area.getType().equals(AreaTypeEnum.CITY.getType())){
                List<Area> children = area.getChildren();
                List<Integer> collect = children.stream().map(item -> item.getId()).collect(Collectors.toList());
                areaList.addAll(collect);
            }
        }
        if (!StringUtils.isEmpty(reqVO.getInfoNme())){

        }
        PageResult<SupplyInfoRespVO> page = supplyInfoMapper.selectJoinPage(reqVO, SupplyInfoRespVO.class, new MPJLambdaWrapperX<SupplyInfoDO>()
                .betweenIfPresent(SupplyInfoDO::getCreateTime, reqVO.getCountTime())
                .inIfPresent(SupplyInfoDO::getCountName, strings)
                .rightJoin(BusinessUserDO.class, BusinessUserDO::getUserId, SupplyInfoDO::getUserId)
                .selectAll(SupplyInfoDO.class)
                .selectAs(BusinessUserDO::getAreaId, SupplyInfoRespVO::getAreaId)
                .eq(SupplyInfoDO::getInfoType, reqVO.getType())
                .in(!CollectionUtil.isEmpty(areaList),BusinessUserDO::getAreaId, areaList)
                .orderByDesc(SupplyInfoDO::getCreateTime));
        List<DictDataRespDTO> unit = dataApi.getDictDataList("unit");
        if (!CollectionUtil.isEmpty(page.getList())) {
            List<SupplyInfoRespVO> collect = page.getList().stream().peek(item -> {
                String format = AreaUtils.format(item.getAreaId(), " ");
                item.setAreaName(format);
                unit.forEach(dict -> {
                    if (dict.getValue().equals(String.valueOf(item.getUnit()))) {
                        item.setUnitName(dict.getLabel());
                    }
                });
            }).collect(Collectors.toList());
            page.setList(collect);
        }
        return page;

    }

    /**
     * 生成信息的小程序码
     * @param supplyInfoId
     * @param userId
     * @return
     */
    @Override
    public byte[] generateCode(Long supplyInfoId, Long userId) {
        String accessToken = WeChatUtils.getAccessToken(accessTokenUrl, appid, appSecret);
        return requestQrCodeUrl(supplyInfoId, userId, accessToken);
    }

    private byte[] requestQrCodeUrl(Long supplyInfoId, Long userId, String accessToken) {

        //env_version：要打开的小程序版本。正式版为 “release”，体验版为 “trial”，开发版为 “develop”。默认是正式版

        Map<String, Object> body = new HashMap<>();
        body.put("scene", "shareId/" + userId +"*id/" + supplyInfoId);
        body.put("access_token", accessToken);
        body.put("page", "pages/indexs/detail/supply-demand-detail");
        ByteArrayOutputStream bos = WeChatUtils.getWechatQrcodeByHttpURL(unlimitedQRCodeUrl, body);
        return bos.toByteArray();
    }

    /**
     * 生成小程序码
     * @param userId
     * @return
     */
    @Override
    public byte[] getPosterCode(Long userId) {

        //env_version：要打开的小程序版本。正式版为 “release”，体验版为 “trial”，开发版为 “develop”。默认是正式版

        String accessToken = WeChatUtils.getAccessToken(accessTokenUrl, appid, appSecret);

        Map<String, Object> body = new HashMap<>();
        body.put("scene", "shareId/" + userId);
        body.put("access_token", accessToken);
        //body.put("page", "pages/indexs/index");
        //body.put("env_version", "trial");
        ByteArrayOutputStream bos = WeChatUtils.getWechatQrcodeByHttpURL(unlimitedQRCodeUrl, body);
        return bos.toByteArray();

    }

    public void sendMessage(Long saleUserId, Long buyUserId) {
        MessageBoardSaveReqVO messageBoardSaveReqVO = new MessageBoardSaveReqVO();
        messageBoardSaveReqVO.setContent("担责担保订单已生成");
        messageBoardSaveReqVO.setTypeId(0);
        messageBoardSaveReqVO.setInfoId(0L);
        messageBoardSaveReqVO.setSendId(saleUserId);
        messageBoardSaveReqVO.setReceiveId(buyUserId);
        messageBoardSaveReqVO.setChatId(SnowflakeIdGeneratorUtil.generateLongId());
        messageBoardService.createOrderMessageBoard(messageBoardSaveReqVO);
    }

    private BusinessUserDO authBusinessUser() {
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        BusinessUserDO businessUserDO = businessUserMapper.selectOne(new LambdaQueryWrapper<BusinessUserDO>().eq(BusinessUserDO::getUserId, loginUserId));
        if (businessUserDO == null) {
            throw exception(USER_NOT_EXISTS);
        }
        if (!BusinessUserEnum.AUDITED_STATUS.getCode().equals(businessUserDO.getStatus())) {
            throw exception(BUSINESS_STATUS_AUDIT);
        }
//        if (!BusinessUserEnum.AUTHENTICATED_AUTH.getCode().equals(businessUserDO.getIsAuth())) {
//            throw exception(BUSINESS_STATUS_AUTH);
//        }
        return businessUserDO;
    }

}
